package com.vic.sb36.biz.impl;

import com.vic.sb36.biz.UserBiz;
import com.vic.sb36.entity.Order;
import com.vic.sb36.service.OrderService;
import com.vic.sb36.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserBizImpl implements UserBiz {

    @Autowired
    UserService userService;

    @Autowired
    OrderService orderService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void testTx() {

        Long userId = 1L;

        Order order = new Order();
        order.setUserId(userId);
        order.setGoodsName("电脑1");
        order.setQuantity(2);
        order.setDeleteFlag(1);

        String remark = "suc";

        try {
            // addOrder 也加了事务，因为都使用了事务，默认的事务传播机制为 PROPAGATION_REQUIRED，所以这过程中会使用同一个事务。
            // 在 addOrder 方法中，如果抛出了异常，事务会被标记为 rollback-only，在上层 testTx 方法中虽然 catch 了异常，但不会影响标记，所以A方法继续正常执行，当A方法最后执行commit时，
            // 发现事务已被标记为 rollback-only，所以会报 Transaction rolled back because it has been marked as rollback-only。
            orderService.addOrder(order);

        } catch (Exception e) {

            // 保存订单失败
            remark = "fail";

            // 捕获了 addOrder 方法中抛出的异常，打印：异常啦
            System.out.println(e.getMessage());

            // 如果这里放开，那么异常继续往上传递，就不会出现 rollback-only 问题，事务回滚成功。
            throw e;
        }

        // 更新用户
        userService.updateRemark(userId, remark);

    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void testTx1() {

        Long userId = 1L;

        Order order = new Order();
        order.setUserId(userId);
        order.setGoodsName("电脑1");
        order.setQuantity(2);
        order.setDeleteFlag(1);

        String remark = "suc";

        try {
            // addDetailWithNewTx 也加了事务，但是新创建一个事务，与上层 testTx 方法是不同的事务，
            // 所以，addDetailWithNewTx 抛出异常时，此方法正常回滚了，上层 testTx 方法 catch 了异常，如果只是打印异常信息，而不是往上抛出，则 testTx 方法可正常执行commit操作。
            orderService.addDetailWithNewTx(order);

        } catch (Exception e) {

            // 保存订单失败
            remark = "fail";

            // 捕获了 addOrder 方法中抛出的异常，打印：异常啦
            System.out.println(e.getMessage());

            // 如果这里放开，那么异常继续往上传递，就不会出现 rollback-only 问题，事务回滚成功。
//            throw e;
        }

        // 更新用户
        userService.updateRemark(userId, remark);

    }

}
